<template>
  <div
    class="moveBg"
    @mousemove="mouseMove"
    @mouseup="mouseUp"
    @mouseleave.stop="mouseLeave"
    :style="{
      pointerEvents: isBoxResizing || isBoxMoving ? 'auto' : 'none',
      zIndex: isFullScreen ? 999 : props.app?.isTop ? 98 : 88,
    }"
  >
    <div
      class="box"
      :style="{
        left: nowRect.left + 'px',
        top: nowRect.top + 'px',
        bottom: nowRect.bottom + 'px',
        right: nowRect.right + 'px',
      }"
      :class="getExtBoxClasses()"
    >
      <div class="box-top">
        <div class="box-top-left" @mousedown="resizeMouseDown"></div>
        <div class="box-top-center" @mousedown="resizeMouseDown"></div>
        <div class="box-top-right" @mousedown="resizeMouseDown"></div>
      </div>
      <div class="box-center">
        <div class="box-center-left" @mousedown="resizeMouseDown"></div>
        <div class="box-center-center loader" @mousedown.stop="showThisApp">
          <div
            class="app-bar"
            :style="{ backgroundColor: props.app?.titleBgColor }"
            @mousedown.stop="positionMouseDown"
            v-on:dblclick="appBarDoubleClicked"
          >
            <div class="controll">
              <div class="close" @click.stop="closeAppHandle"></div>
              <div class="min" @click.stop="hideAppHandle"></div>
              <div
                class="full"
                :class="props.app?.disableResize ? 'full-disabled' : ''"
                @click="switchFullScreen"
              ></div>
            </div>
            <div class="title" :style="{ color: props.app?.titleColor }">
              {{ appData.title || props.app?.title }}
            </div>
          </div>
          <div class="app-body">
            <component :is="com" :app="props.app" @api="appEvent"></component>
          </div>
        </div>
        <div class="box-center-right" @mousedown="resizeMouseDown"></div>
      </div>
      <div class="box-bottom">
        <div class="box-bottom-left" @mousedown="resizeMouseDown"></div>
        <div class="box-bottom-center" @mousedown="resizeMouseDown"></div>
        <div class="box-bottom-right" @mousedown="resizeMouseDown"></div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, defineAsyncComponent, defineProps, watch, markRaw } from "vue";
//  import SystemFinder from "@/view/system/finder";

import { isMobile } from "@/utils/common";
import { useAppStore } from "@/store/modules/app";
import { storeToRefs } from "pinia";
import tool from "@/helper/tool";

const appStore = useAppStore();
const { openAppList } = storeToRefs(appStore);
const { openApp, hideApp, showApp, closeApp, openWithData, closeWithPid } = appStore;

const appData = ref<any>({});
// const defaultIndex = ref(10);
// const activeIndex = ref(20);
const isBoxMoving = ref(false);
const startPosition = ref({ x: 0, y: 0 });
const nowRect = ref({
  left: 100,
  right: 100,
  top: 100,
  bottom: 100,
});
const startRect = ref({
  left: 0,
  right: 0,
  top: 0,
  bottom: 0,
});
const isBoxResizing = ref(false);
const moveDirection = ref<Boolean | String>();
const isMaxShowing = ref(false);
const isFullScreen = ref(false);

const props = defineProps({
  app: <any>{},
});

watch(
  () => props.app,
  () => {
    console.log();

    appData.value = Object.assign(props.app, {
      title: appData.value.title || props.app.title,
    });
  }
);

const com = ref<any>();

let _com = <any>{};
switch (props.app?.component) {
  case "SystemAbout":
    _com = defineAsyncComponent(() => import("@/view/system/about.vue"));
    break;
  case "SystemFinder":
    _com = defineAsyncComponent(() => import("@/view/system/finder.vue"));
    break;
  case "SystemSetting":
    _com = defineAsyncComponent(() => import("@/view/system/setting.vue"));
    break;
  case "SystemStore":
    _com = defineAsyncComponent(() => import("@/view/system/store.vue"));
    break;
  case "SystemTask":
    _com = defineAsyncComponent(() => import("@/view/system/task.vue"));
    break;
  case "Demo":
    _com = defineAsyncComponent(() => import("@/view/demo/demo.vue"));
    break;
  case "DemoDock":
    _com = defineAsyncComponent(() => import("@/view/demo/dock.vue"));
    break;
  case "DemoUnResize":
    _com = defineAsyncComponent(() => import("@/view/demo/unresize.vue"));
    break;
  case "DemoUnClose":
    _com = defineAsyncComponent(() => import("@/view/demo/unclose.vue"));
    break;
  case "DemoHideDesktop":
    _com = defineAsyncComponent(() => import("@/view/demo/hidedesktop.vue"));
    break;
  case "DemoColorFull":
    _com = defineAsyncComponent(() => import("@/view/demo/colorfull.vue"));
    break;
  case "DemoCamera":
    _com = defineAsyncComponent(() => import("@/view/demo/camera.vue"));
    break;
  case "DemoMultiTask":
    _com = defineAsyncComponent(() => import("@/view/demo/multitask.vue"));
    break;
  case "DemoWeb":
    _com = defineAsyncComponent(() => import("@/view/demo/web.vue"));
    break;
  case "VideoPlayer":
    _com = defineAsyncComponent(() => import("@/view/system/videoPlayer.vue"));
    break;
  case "Account":
    _com = defineAsyncComponent(() => import("@/view/system/account.vue"));
    break;
  case "LogMonit":
    _com = defineAsyncComponent(() => import("@/view/system/logMonit.vue"));
    break;
  case "IconFont":
    _com = defineAsyncComponent(() => import("@/view/system/iconfont.vue"));
    break;
  case "SpareTimeWorker":
    _com = defineAsyncComponent(() => import("@/view/system/spareTimeWorker.vue"));
    break;
  case "Wallhaven":
    _com = defineAsyncComponent(() => import("@/view/system/wallhaven.vue"));
    break;
  default:
    break;
}
com.value = markRaw(_com);
// com.value = markRaw(
//   defineAsyncComponent(() => import(`../view/${props.app?.componentPath}.vue`))
// );
// const SystemAbout = defineAsyncComponent(() => import("@/view/system/about"));
// const SystemFinder = defineAsyncComponent(() => import("@/view/system/finder.vue"));
// SystemSetting: defineAsyncComponent(() => import("@/view/system/setting")),
// SystemStore: defineAsyncComponent(() => import("@/view/system/store")),
// SystemTask: defineAsyncComponent(() => import("@/view/system/task")),
// Demo: defineAsyncComponent(() => import("@/view/demo/demo")),
// DemoDock: defineAsyncComponent(() => import("@/view/demo/dock")),
// DemoUnResize: defineAsyncComponent(() => import("@/view/demo/unresize")),
// DemoUnClose: defineAsyncComponent(() => import("@/view/demo/unclose")),
// DemoHideDesktop: defineAsyncComponent(() => import("@/view/demo/hidedesktop")),
// DemoColorFull: defineAsyncComponent(() => import("@/view/demo/colorfull")),
// DemoCamera: defineAsyncComponent(() => import("@/view/demo/camera")),
// DemoMultiTask: defineAsyncComponent(() => import("@/view/demo/multitask")),
// DemoWeb: defineAsyncComponent(() => import("@/view/demo/web")),
// const VideoPlayer = defineAsyncComponent(() => import("@/view/system/videoPlayer"));

setReact();
//移动端直接最大化
if (isMobile()) {
  isMaxShowing.value = true;
  isFullScreen.value = false;
}

function setReact() {
  if (props.app?.width) {
    nowRect.value.left = nowRect.value.right =
      (document.body.clientWidth - props.app?.width) / 2;
  }
  if (props.app?.height) {
    nowRect.value.bottom = (document.body.clientHeight - props.app?.height) / 2;
    nowRect.value.top = (document.body.clientHeight - props.app?.height) / 2;
  }
}
/**
 * @description: 监听APP发送的事件 转发或处理到桌面组件中
 */
function appEvent(e) {
  switch (e.event) {
    case "windowMaxSize":
      if (props.app?.disableResize) {
        return;
      }
      isMaxShowing.value = true;
      isFullScreen.value = false;
      break;
    case "windowNormalSize":
      if (props.app?.disableResize) {
        return;
      }
      isMaxShowing.value = false;
      isFullScreen.value = false;
      break;
    case "windowFullSize":
      if (props.app?.disableResize) {
        return;
      }
      isFullScreen.value = true;
      isMaxShowing.value = true;
      break;
    case "windowMinSize":
      hideAppHandle();
      break;
    case "windowClose":
      closeAppHandle();
      break;
    case "openApp":
      if (e.data && e.app) {
        openWithData({
          app: tool.getAppByKey(e.app),
          data: e.data,
        });
      } else {
        openApp(tool.getAppByKey(e.app));
      }
      break;
    case "closeApp":
      if (e.pid) {
        closeWithPid(e.pid);
      }
      if (e.app) {
        closeApp(tool.getAppByKey(e.app));
      }
      break;
    case "setWindowTitle":
      appData.value.title = e.title || props.app?.title;
      break;
    default:
  }
}
/**
 * @description: 关闭当前应用
 */
function closeAppHandle() {
  closeApp(props.app);
}
/**
 * @description: 隐藏当前应用
 */
function hideAppHandle() {
  hideApp(props.app);
}
function showThisApp() {
  showApp(props.app);
}
/**
 * @description: 全屏切换
 */
function switchFullScreen() {
  if (props.app?.disableResize) {
    return;
  }
  isFullScreen.value = !isFullScreen.value;
  if (isFullScreen.value) {
    isMaxShowing.value = true;
  } else {
    isMaxShowing.value = false;
  }
}
/**
 * @description: 返回应用配置的样式类
 */
function getExtBoxClasses() {
  let str = "";
  if (!isBoxResizing.value && !isBoxMoving.value) {
    str += "box-animation ";
  }
  if (isMaxShowing.value) {
    str += "isMaxShowing ";
  }
  if (isFullScreen.value) {
    str += "isFullScreen ";
  }
  if (props.app?.disableResize) {
    str += "resize-disabled ";
  }
  if (openAppList.value[openAppList.value.length - 1].pid == props.app?.pid) {
    str += "isTop ";
  }
  return str;
}
/**
 * @description: 标题栏被双击 缩放
 */
function appBarDoubleClicked() {
  if (props.app?.disableResize) {
    return;
  }
  isMaxShowing.value = !isMaxShowing.value;
  if (!isMaxShowing.value) {
    isFullScreen.value = false;
  }
}
/**
 * @description: 鼠标按下
 */
function positionMouseDown(e) {
  // console.warn("positionMouseDown")
  showThisApp();
  if (isFullScreen.value || isMaxShowing.value) {
    return;
  }
  startRect.value = {
    left: nowRect.value.left,
    right: nowRect.value.right,
    top: nowRect.value.top,
    bottom: nowRect.value.bottom,
  };
  startPosition.value.x = e.clientX;
  startPosition.value.y = e.clientY;
  isBoxMoving.value = true;
}
function mouseUp() {
  isBoxMoving.value = false;
  isBoxResizing.value = false;
  moveDirection.value = false;
}
function mouseLeave() {
  isBoxMoving.value = false;
  isBoxResizing.value = false;
  moveDirection.value = false;
}
function mouseMove(e) {
  if (isBoxResizing.value) {
    isFullScreen.value = false;
    isMaxShowing.value = false;
    switch (moveDirection.value) {
      case "box-top-left":
        nowRect.value.top = startRect.value.top + (e.clientY - startPosition.value.y);
        nowRect.value.left = startRect.value.left + (e.clientX - startPosition.value.x);
        break;
      case "box-top-center":
        nowRect.value.top = startRect.value.top + (e.clientY - startPosition.value.y);
        break;
      case "box-top-right":
        nowRect.value.top = startRect.value.top + (e.clientY - startPosition.value.y);
        nowRect.value.right = startRect.value.right - (e.clientX - startPosition.value.x);
        break;
      case "box-center-left":
        nowRect.value.left = startRect.value.left + (e.clientX - startPosition.value.x);
        break;
      case "box-bottom-left":
        nowRect.value.left = startRect.value.left + (e.clientX - startPosition.value.x);
        nowRect.value.bottom =
          startRect.value.bottom - (e.clientY - startPosition.value.y);
        break;
      case "box-bottom-center":
        nowRect.value.bottom =
          startRect.value.bottom - (e.clientY - startPosition.value.y);
        break;
      case "box-center-right":
        nowRect.value.right = startRect.value.right - (e.clientX - startPosition.value.x);
        break;
      case "box-bottom-right":
        nowRect.value.right = startRect.value.right - (e.clientX - startPosition.value.x);
        nowRect.value.bottom =
          startRect.value.bottom - (e.clientY - startPosition.value.y);
        break;
      default:
    }
    return;
  }
  if (isBoxMoving.value) {
    isFullScreen.value = false;
    isMaxShowing.value = false;
    nowRect.value.left = startRect.value.left + (e.clientX - startPosition.value.x);
    nowRect.value.right = startRect.value.right - (e.clientX - startPosition.value.x);
    nowRect.value.top = startRect.value.top + (e.clientY - startPosition.value.y);
    nowRect.value.bottom = startRect.value.bottom - (e.clientY - startPosition.value.y);
    return;
  }
}
function resizeMouseDown(e) {
  if (props.app?.disableResize) {
    return;
  }
  showThisApp();
  if (isFullScreen.value || isMaxShowing.value) {
    return;
  }
  startRect.value = {
    left: nowRect.value.left,
    top: nowRect.value.top,
    right: nowRect.value.right,
    bottom: nowRect.value.bottom,
  };
  startPosition.value.x = e.clientX;
  startPosition.value.y = e.clientY;
  isBoxResizing.value = true;
  moveDirection.value = e.target.className;
}
</script>
<style scoped lang="scss">
.moveBg {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  .isTop {
    .box-center-center {
      box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.5) !important;
      filter: none !important;
    }
  }
  .isMaxShowing {
    left: -5px !important;
    right: -5px !important;
    top: 23px !important;
    bottom: 41px !important;
  }

  .isFullScreen {
    position: fixed !important;
    z-index: 999 !important;
    bottom: -5px !important;
    top: -5px !important;
  }

  .isMaxShowing .box-center-center,
  .isFullScreen .box-center-center {
    border-radius: 0px !important;
  }
  .box-animation {
    transition: width 0.1s, height 0.1s, left 0.1s, right 0.1s, top 0.1s, bottom 0.1s;
  }
  .resize-disabled {
    .box-top,
    .box-top-left,
    .box-top-center,
    .box-top-right,
    .box-left,
    .box-center-left,
    .box-center-right,
    .box-right,
    .box-bottom,
    .box-bottom-left,
    .box-bottom-center,
    .box-bottom-right {
      cursor: default !important;
    }
  }
  .box {
    --resize: 5px;
    --resize-bg: transparent;
    --resize-main: transparent;
    --resize-bg-main: transparent;
  }

  .box {
    display: flex;
    flex-direction: column;
    position: absolute;
    pointer-events: auto;

    .box-top {
      display: flex;
      flex-direction: row;
      .box-top-left {
        width: var(--resize);
        height: var(--resize);
        background: var(--resize-bg);
        cursor: nw-resize;
      }

      .box-top-center {
        height: var(--resize);
        background: var(--resize-bg-main);
        cursor: n-resize;
        flex-grow: 1;
      }

      .box-top-right {
        width: var(--resize);
        height: var(--resize);
        background: var(--resize-bg);
        cursor: ne-resize;
      }
    }

    .box-center {
      display: flex;
      flex-direction: row;
      flex-grow: 1;

      .loader {
        display: flex;
        flex-grow: 1;
        flex-direction: column;
        width: 100%;
      }
      .box-center-left {
        width: var(--resize);
        height: 100%;
        background: var(--resize-bg-main);
        cursor: w-resize;
      }

      .box-center-center {
        height: 100%;
        flex-grow: 1;
        display: flex;
        flex-direction: column;
        border-radius: 10px;
        box-shadow: 0px 0px 3px #999;
        background: rgba(255, 255, 255, 0.8);
        backdrop-filter: blur(20px);
        overflow: hidden;
        filter: grayscale(1) brightness(0.9);
        .app-bar {
          height: 40px;
          background: rgba(255, 255, 255, 0.5);
          backdrop-filter: blur(20px);
          display: flex;
          flex-direction: row;
          justify-content: center;
          align-items: center;
          white-space: nowrap;
          text-overflow: ellipsis;
          overflow: hidden;
          .title {
            flex-grow: 1;
            text-align: center;
            margin-right: 84px;
            font-weight: 500;
            text-shadow: none;
            font-size: 13px;
            cursor: move;
            color: #333;
          }
          .controll {
            display: flex;
            justify-content: center;
            align-items: center;
            margin-left: 15px;
            div {
              border-radius: 100%;
              height: 14px;
              width: 14px;
              margin-right: 8px;
              cursor: pointer;
            }
            .close {
              background: #fc605c;
            }
            .close:hover {
              background: #cc2c26;
            }
            .min {
              background: #fcbb40;
            }
            .min:hover {
              background: #c28719;
            }
            .full {
              background: #34c648;
            }
            .full:hover {
              background: #1f942e;
            }

            .full-disabled {
              background: #ccc !important;
            }
          }
        }

        .app-body {
          flex-grow: 1;
          display: flex;
          flex-direction: column;
          justify-content: center;
          align-items: center;
          height: 0;
        }
      }
      .box-center-right {
        width: var(--resize);
        height: 100%;
        background: var(--resize-bg-main);
        cursor: e-resize;
      }
    }

    .box-bottom {
      display: flex;
      flex-direction: row;
      .box-bottom-left {
        width: var(--resize);
        height: var(--resize);
        background: var(--resize-bg);
        cursor: sw-resize;
      }

      .box-bottom-center {
        height: var(--resize);
        background: var(--resize-bg-main);
        cursor: s-resize;
        flex-grow: 1;
      }

      .box-bottom-right {
        width: var(--resize);
        height: var(--resize);
        background: var(--resize-bg);
        cursor: se-resize;
      }
    }
  }
}
</style>
